步进电机是步进电机是将电脉冲信号转变为角位移或线位移的开环控制电机,是现代数字程序控制系统中的主要执行元件,应用极为广泛–百度百科
步进电机的特点就是能够通过脉冲精准控制位置并能提供大扭力,输入一个脉冲转动一个角度(称为步距角)。步进电机的特点使得应用场合非常广泛,如ATM机、刻字机、医疗设备、机器人等等
步进电机带大负载工作时,如果让步进电机均速运行会出现一个抖动的现象(这是由于惯性引起的),因此需要在控制时尽量让步进电机运动平滑一些(θ是位置,t是时间)
本文介绍如何实现步进电机线速度控制,所谓的线速度就是工作中步进电机转动的速度。内容主要参考ATMEL的一片文章以及一份源码
参考文章:Generate stepper-motor speed profiles in real time
参考文档:AVR446: Linear speed control of stepper motor
源码:sound code
Introduce
本文主要描述怎样去实现步进电机的线速度控制,步进电机是一个电磁设备将数字脉冲转换为机械轴转动,使用这种电机有很多优点,例如因为没有电刷与触点存在所以使用跟简单、低成本、高可靠性、低速时转矩大、运动精度高,许多具有步进电机的系统在改变速度的时候需要控制加速度/减速度。本文也会提供一个例程,能够控制加速度、减速度、最大速度以及位置。内容大部分参考上面提供的相关参考资料
这种线性速度控制是基于2005年1月“嵌入式系统编程”提出的一种算法,D. Austin的一篇“实时生成步进电机速度曲线”文章。该算法只使用简单的定点算术运算没有数据表,可以实时地进行参数化和计算
Theory
Stepper motor
本文内容涵盖了步进电机线速度控制原理以及在微控制器中的实现,这里默认读者已经熟悉步进电机的相关操作,如果想了解更多步进电机相关的内容可以参考下面D.W.Jones的一篇文章:Control of Stepper Motors
Full vs. half stepping
两种常见的步进电动机类型是双极电动机和单极电动机。双极和单极电机是相似的,除了单极在每个绕组上有一个中心抽头
双极型步进电机需要电流在两个方向上通过绕组驱动,需要一个完整的桥驱动器。单极步进电机允许一个更简单的驱动电路,限制电流向一个方向流动,单极步进电机的主要缺点是有限的能力去激励所有的绕组,导致较低的扭矩,单极步进电机可以通过断开中心抽头当做双极步进电机使用
Full vs. half stepping
步进电机使用全步进模式依次对每个线圈通电,这样有四种不同的位置,如Full-stepping行显示。而通过同时驱动两个绕组,步进电机被困在全步的中间位置,也就是我们所知的半步。半步有8个位置,如Half-stepping行显示,当为两个绕组供电时,转矩比一个绕组高出约1.4倍,但是以两倍的功耗为代价。一个机械周期(转动)通常包括数个电气周期,可以理解为步进电机转动一个步距角需要数个电脉冲脉冲
Electric polarity | Winding A | + | + | - | - | - | + | ||
---|---|---|---|---|---|---|---|---|---|
Winding B | + | + | + | - | - | - | |||
Electrical cycle part | Full-stepping | 1 | 2 | 3 | 4 | ||||
Half-stepping | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
Speed properties
步进电机的一个缺点是高速时转矩(转动力矩)会被限制,步进电机的转矩会随着速度的增加而减小,步进电机在达到谐振速度时转矩也会降低,谐振速度取决于步进电机的驱动方案和负载(T=转矩,w=速度)
Fundamental stepper motor equations
要使得步进电机转动,经过线圈的电流必须按照一定的顺序改变,可以通过一个特定方向的脉冲来实现。要使电机恒速装懂,那么给电机的脉冲也是在一定频率上的
一个人计数器用于产生脉冲,计数器频率为ft[Hz]。计数器c产生延迟:
步进电机的步距角为α,位置为θ,速度为ω,可以得到:
spr为电机转一圈所需要的步数,n为步数,1rad/sec = 9,55rpm
Linear speed ramp
要使启动和停止步进电机时平稳,需要对它进行一个加减速控制,如下图
步进电机脉冲之间的延迟δt控制转速,为了步进电机尽可能的接近速度斜率,必须计算这些时间延迟。通过定时器的频率决定每步之间的时间从而解决时间延迟的问题,实现离散步长控制步进电机运动
Exact calculations of the inter-step delay
第一个计数器延迟C0以及之后的Cn:
MCU的计算能力有限,计算开方运算是非常耗时的,因此需要考虑减少复杂度。当计数值为n时,使用泰勒公式展开得到:
这样的计算比开放要快得多,但是在n = 1时会引进0.44的误差,通过将C0乘以0.676的方法来进行补偿
Change in acceleration
如后面的Appendix所示,加速度由C0和n给出,如果加速度或减速度发生变化,必须计算一个新的n值。时间tn和n作为电机加速度、速度和步距角的函数,得:
整合方程得:
这表明,到达给定速度所需的步数与加速度成反比:
意味着可以通过n来改变加速度或减速度:
移动一个给定得部署,减速必须在正确得步数开始到0速度结束,可以通过下面公式得到n1:
Implementation
本文所描述的源码以及参考文章都在前后给出,源码使用的是Atmel的AVR单片机实现,程序使用C语言编写,用户可以打开源码的中的’readme.html’文件来了解所有文档、源码和编译的信息
例程演示了步进电机的线速度控制,用户可以通过串口发送不同的命令来控制步进电机的速度曲线,然后AVR单片机控制它连接的步进电机运动
源码分为三个主要的部分:
main.c。有一个菜单和一个命令接口,让用户通过串口上位机连接进行控制步进电机
speed_cntr.c。计算所需要的数据并产生步进脉冲让步进电机按预期的速度运动
sm_driver.c。计算步数和输出控制步进电机运动的正确信号
控制步进电机需要四个描述速度曲线的参数,速度从零开始加速到指定的速度,然后速度保持恒定直到开始简述,最后在给定的步数内减速到0,速度曲线如下
相关参数如下:
- step-移动的步数
- accel-加速度
- decel-减速度
- speed-最大速度
Menu and command interface
要使用例程,用户必须通过串口把PC端和AVR连接起来,然后UART配置为波特率-19200,数据位-8,无奇偶校验,停止位-1。通过上位机可以发哦那个不同的命令来控制步进电机,并能从应用中获取信息
UART接收中断程序(uart.c)存储接收的字符串在接收缓冲区,当接收到
如发送一个’?’命令,将会显示帮助信息在终端上
1 | -------------------------------------------------------------- |
在菜单显示或者执行命令后,会显示
1 | Motor pos: 0 a:4000 d:4000 s:2000 m:400 |
例程应用会给出当前电机位置、加速度、减速度和速度,以及移动的步数。由三种方法使步进电机运动:
- 按
-步进电机按程序给定的设置运行 - m[data]-步进电机在设置下移动[data]步
- move[steps] [accel] [decel] [speed]-移动[steps]步,设置 [accel] [decel] [speed]
当步进电机开始运行时,会显示‘Running…’,只要步进电机在运行中,新的命令不会被接收。在停止时会显示’OK’,这时才会接收新命令
Speed controller
速度控制器计算并生成速度曲线,速度控制器如下图
函数Move()首先会计算所有的参数然后存储在speed ramp数据结构体中,然乎使能定时器中断,定时器按计算的速度斜率产生中断,在中断中调用Step_Counter()函数移动步进电机
Setup calculations
在例程中,为每个命令都需要重新计算速度参数和一C0作为步进电机移动的开始,在实际应用中如果对速读参数改动非常小则不需要每次计算,参数可以预先计算好
为了让运算速度更快,应该尽量避免使用浮点运算,因此为了保证精度可以对变量进行适当的缩放(如放大100倍)。预编译也可以减少运算时间,在smdriver.h文件下:
速度定义(这里放大100倍):
加速度定义:
速度曲线的计算有两种情况:
- 一直加速到期望的速度
- 还没加速到期望的速度就得进行减速
Acceleration continues until desired speed is reached
在减速开始前达到期望得速度
max_s_lim是加速度期望速度得步数
accel_lim是减速开始前得步数
如果max_s_lim小于accel_lim,加速度被最大速度限制,decal_val为
Deceleration starts before desired speed is reached
在达到期望速度之前开始减速
如果max_s_lim大于accel_lim,加速度受限于减速开始,decal_val为
Timer interrupt
定时器中断产生步进脉冲(调用StepCounter())函数,并且只有当步进电机运行时才会产生中断,定时器中断按照速度曲线运行在电机得四种不同得状态下
在中断中实现四种状态得切换
当程序开始或步进电机停止时,处于STOP状态下。当计算完成,一个新的状态置位并且使能中断。当移动得步数大于1,状态变为ACCEL,如果只有一步,状态变为DECEL
当处于ACCEL状态时,步进电机会加速到期望得速度进入RUN状态或者必须开始减速而进入DECEL状态。当处于RUN状态时,步进电机保持在最大速度知道必须开始减速而进入DECEL状态
最后保持DECEL状态运行完减速得步数后速度变为0进入STOP状态
Calculations and counters
在加速和减速过程得每一步,必须计算出来一个新的延迟值。计算结果会有一个余数,为了提高精度,该余数会累计到下一个计算中
为了追踪位置和改变状态,需要一些用于计数得变量
step_count。记录步数,在加速过程从0开始并在减速完成后与设定得步数值一致
accel_count。用于控制加速/减速。在ACCEL状态时不断递增直到ZCCEL状态结束。在DECEL状态时,它被设置为decel_val(该值是一个负数)一直递增到0运动结束,状态被设为STOP
decel_start。告知何时开始减速,当step_count等于decel_start时进入DECEL状态
Stepper motor driver
步进电机驱动生成一个正确得脉冲序号开控制步进电机按照命令方向进行移动,步进电机驱动框图如下
在每次调用Step_Counter时,步数计数器都会递增或递减(跟方向有关),当使用全步时,计数器值从0到3,使用半步则是从0到7。这个值等于步进电机在一个电循环中的不同位置。用作步骤表的索引,并且给出正确的信号
Code size and speed
完整得例程占用4K大小程序存储器,速度控制和步进电机驱动占了1.5K,删除预编译得参数可以使得代码减速(运行速度可能会变慢)
当调用Move()时,在定时器中断开始前就完成计算,从调用函数到步进电机的启动其中大约会有1.5ms的延迟,定时器中断在执行加减速计算过程中,每运算一次大约需要200us,运行在恒速的时候计算一次大约需要35us。最大的速度受到加减速的限制,对于一个400步每圈的步进电机来说,最大速度为
在其他应用上执行此代码,必须考虑中断的问题。如果步进电机的定时器中断被另一个中断给打断,步进电机的速度会变化(非预期变化),在特定的应用程序中可能不是很关键,但是让程序运行稳定总是对的
Appendix
Counter delay
给定时刻的速度为:
位置可由下面公式得到:
n个步进脉冲后的位置θ = nα 得:
两步之间得延迟为:
最后计数器延迟的表达式为:
将第一步和第n步代入表达式得:
Inter-step delay
使用泰勒级数展开约得:
代入得:
最后,延迟表达式近似为:
Literature references
参考文章:Generate stepper-motor speed profiles in real time
参考文档:AVR446: Linear speed control of stepper motor
参考文档:Control of Stepper Motors
源码:sound code